package com.namo.ccharticle.service.impl;

import cn.hutool.core.text.UnicodeUtil;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.namo.ccharticle.dao.ArticleMapper;
import com.namo.ccharticle.dao.ArticleTypeMapper;
import com.namo.ccharticle.dao.TypeMapper;
import com.namo.ccharticle.entity.Article;
import com.namo.ccharticle.entity.ArticleType;
import com.namo.ccharticle.entity.Type;
import com.namo.ccharticle.entity.mongo.Content;
import com.namo.ccharticle.entity.mongo.Covers;
import com.namo.ccharticle.service.ArticleService;
import com.namo.cchcommon.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author WangXin
 * @date 2021/5/15 14:52
 */
@Service
@Slf4j
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    ArticleMapper articleMapper;


    @Autowired
    ArticleTypeMapper articleTypeMapper;


    @Autowired
    TypeMapper typeMapper;


    @Autowired
    Gson gson;

    @Autowired
    MongoTemplate mongoTemplate;

    /**
     * 获取文章列表
     * @return
     */
    @Override
    public List<Article> getArticleList() {
        try {
            List<Article> articles = articleMapper.selectAll();
            log.info("查询到文章列表");
            return articles;
        } catch (Exception e) {
            log.error("查询失败=>" + e.getMessage());
            throw new ApiException(500L, "查询失败");
        }
    }

    /**
     * 添加文章
     * @param reqObject
     * @return
     */
    @Override
    public Object addArticle(JsonObject reqObject) {

        //todo 优化删除多余图片，异常捕获，操作管理者ID，创建时间，更新时间
        String title = null;
        String content = null;
        JsonArray startUps = null;
        JsonArray types = null;
        JsonArray covers = null;

        try {
            title = reqObject.get("title").getAsString();
            content = reqObject.get("content").getAsString();
            startUps = reqObject.get("startUps").getAsJsonArray();
            types = reqObject.get("types").getAsJsonArray();
            covers = reqObject.get("covers").getAsJsonArray();
        } catch (Exception e) {
            log.error("请求参数不正确=>>" + e.getMessage());
            throw new ApiException(500L, "请求参数不正确");
        }

        Article article = new Article();
        article.setId(UUID.randomUUID().toString());
        article.setTitle(title);
        article.setCreateTime(new Date());
        article.setUpdateTime(article.getCreateTime());
        //添加content到mongodb
        Content mongoContent = new Content();
        System.out.println(content);
        content = UnicodeUtil.toUnicode(content,false);
        mongoContent.setContent(content);
        mongoContent.setContentId(UUID.randomUUID().toString());
        Content contents = null;
        try {
            contents = mongoTemplate.insert(mongoContent, "contents");
        } catch (Exception e) {
            log.error("内容插入失败=>>" + e.getMessage());
            throw new ApiException(500L, "添加失败");
        }
        if (contents == null){
            log.error("内容插入失败=>>返回内容为空");
            throw new ApiException(500L, "添加失败");
        }
        log.info("添加内容到mongo成功");
        article.setContentId(contents.getContentId());

        //添加Covers到mongodb
        Covers mongoCovers = new Covers();
        mongoCovers.setCoverId(UUID.randomUUID().toString());
        mongoCovers.setCovers(gson.fromJson(covers,List.class));
        try {
            mongoCovers = mongoTemplate.insert(mongoCovers, "covers");
        } catch (Exception e) {
            log.error("封面插入失败=>>" + e.getMessage());
            throw new ApiException(500L, "添加失败");
        }
        if (mongoCovers == null){
            log.error("封面插入失败=>>返回内容为空");
            throw new ApiException(500L, "添加失败");
        }
        log.info("添加封面到mongo成功");
        article.setCoversId(mongoCovers.getCoverId());
        //添加分类
        for (JsonElement type : types) {
            ArticleType articleType = new ArticleType();
            articleType.setId(UUID.randomUUID().toString());
            articleType.setArticleId(article.getId());
            articleType.setTypeId(type.getAsString());
            articleTypeMapper.insert(articleType);
        }
        log.info("添加类型到mysql成功");
        articleMapper.insert(article);
        log.info("添加文章到mysql成功");
        return article;
    }

    /**
     * 查询单个文章信息
     * @param id
     * @return
     */
    @Override
    public JsonObject getArticleInfo(String id) {
        Article article = null;
        try {
            article = articleMapper.selectByPrimaryKey(id);
        } catch (Exception e) {
            log.error("查询文章错误==>"+e.getMessage());
            throw new ApiException(500L,"查询错误");
        }
        if (article == null){
            log.warn("未查询到文章ID==>"+id);
            throw new ApiException(500L,"查询为空");
        }

        List<ArticleType> articleTypes = articleTypeMapper.selectByArticleId(article.getId());
        List<Type> types = new ArrayList<>();
        for (ArticleType articleType : articleTypes) {
            Type type = typeMapper.selectByPrimaryKey(articleType.getTypeId());
            types.add(type);
        }
        //获得content
        Query contentQuery = new Query();
        contentQuery.addCriteria(Criteria.where("content_id").is(article.getContentId()));
        Content contents = mongoTemplate.findOne(contentQuery, Content.class, "contents");
        String content = contents.getContent();

        //获得covers
        Query coversQuery = new Query();
        contentQuery.addCriteria(Criteria.where("cover_id").is(article.getCoversId()));
        Covers covers = mongoTemplate.findOne(coversQuery, Covers.class, "covers");
        content = UnicodeUtil.toString(content);


        JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("title",article.getTitle());
        jsonObject.addProperty("content",content);
        jsonObject.addProperty("createTime",article.getCreateTime().getTime());
        jsonObject.addProperty("updateTime",article.getUpdateTime().getTime());
        jsonObject.add("covers",gson.fromJson(gson.toJson(covers.getCovers()),JsonArray.class));
        jsonObject.add("types",gson.fromJson(gson.toJson(types),JsonArray.class));
        return jsonObject;
    }
}
